


import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;


/**
 * some helper utilities for work with grid layout. samples of using it see on
 * RoomAllocationPage#createControl
 */
public class GridUtils {
	
	
	/**
	 * GridLayout proxy object. allows to modify grid layout in one line
	 * 
	 * @author AMoiseykin
	 *
	 */
	public static class GridLayoutObj {
		
		private final Composite panel;

		public GridLayoutObj(Composite panel) {
			this.panel = panel;
			
			gridLayout(panel);
		}

		
		/**
		 * makes all column equal width
		 * 
		 * @return
		 */
		public GridLayoutObj equalColumns() {
			return equalColumns(true);
		}

		
		public GridLayoutObj equalColumns(boolean equalColumns) {
			GridUtils.equalColumns(equalColumns, gridLayout(panel));
			return this;
		}


		public GridLayoutObj noMargins() {
			GridUtils.noMargins(gridLayout(panel));
			return this;
		}
		
		
		public GridLayoutObj vertMargin(int value) {
			GridUtils.vertMargin(value, gridLayout(panel));
			return this;
		}
		
		public GridLayoutObj topMargin(int value) {
			GridUtils.topMargin(value, gridLayout(panel));
			return this;
		}
		
		public GridLayoutObj bottomMargin(int value) {
			GridUtils.bottomMargin(value, gridLayout(panel));
			return this;
		}

		
		public GridLayoutObj horzMargin(int value) {
			GridUtils.horzMargin(value, gridLayout(panel));
			return this;
		}
		
		
		public GridLayoutObj numColumns(int value) {
			GridUtils.numColumns(value, gridLayout(panel));
			return this;
		}
		
		public GridLayoutObj vertSpacing(int value) {
			GridUtils.vertSpacing(value, gridLayout(panel));
			return this;
		}
		
		public GridLayoutObj horzSpacing(int value) {
			GridUtils.horzSpacing(value, gridLayout(panel));
			return this;
		}

		public GridLayoutObj noSpacing() {
			vertSpacing(0);
			horzSpacing(0);
			return this;
		}
		
	}


	private static final boolean _DEBUG = true;

	/**
	 * gets layout data from control. if it is not GridData creates new GridData
	 * object and sets it to control
	 * 
	 * @param ctrl
	 * @return
	 */
	public static GridData gridData(Control ctrl) {
		
		GridData gd;
		if (ctrl.getLayoutData() instanceof GridData) {
			gd = (GridData) ctrl.getLayoutData();
		} else {
			gd = new GridData();
			ctrl.setLayoutData(gd);
		}
		return gd;
	}
	
	
	public static GridLayout vertSpacing(int value, GridLayout layout) {
		layout.verticalSpacing = value;
		return layout;
	}

	public static GridLayout horzSpacing(int value, GridLayout layout) {
		layout.horizontalSpacing = value;
		return layout;
	}
	
	public static GridLayout vertMargin(int value, GridLayout gridLayout) {
		gridLayout.marginHeight = value;
		return gridLayout;
	}
	
	
	public static GridLayout topMargin(int value, GridLayout gridLayout) {
		gridLayout.marginTop = value;
		return gridLayout;
	}
	
	public static GridLayout bottomMargin(int value, GridLayout gridLayout) {
		gridLayout.marginBottom = value;
		return gridLayout;
	}

	
	public static GridLayout horzMargin(int value, GridLayout gridLayout) {
		gridLayout.marginWidth = value;
		return gridLayout;
	}
	

	/**
	 * analog of FILL_HORZ attribute in grid data.
	 * 
	 * @param ctrl contorol on which data be set
	 * @return ctrl param
	 */
	public static Control fillHorz(Control ctrl) {
		GridData gd = gridData(ctrl);
		
		gd.horizontalAlignment = SWT.FILL;
		gd.grabExcessHorizontalSpace = true;
		
		return ctrl;
	}


	/**
	 * analog of FILL_VERT attribute in grid data.
	 * 
	 * @param ctrl
	 * @return
	 */
	public static Control fillVert(Control ctrl) {
		GridData gd = gridData(ctrl);
		
		gd.verticalAlignment = SWT.FILL;
		gd.grabExcessVerticalSpace = true;
		
		return ctrl;
	}
	
	
	public static Control fillBoth(Control ctrl) {
		return fillVert(fillHorz(ctrl));
	}
	
	
	/**
	 * sets horizontal span to control's grid data
	 * @param ctrl
	 * 
	 * @return
	 */
	public static Control spanHorz(int span, Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.horizontalSpan = span;
		
		return ctrl;
	}
	

	public static Control spanVert(int span, Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.verticalSpan = span;
		return ctrl;
	}
	
	
	public static Control alignTop(Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.verticalAlignment = SWT.TOP;
		return ctrl;
	}

	
	public static Control alignBottom(Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.verticalAlignment = SWT.BOTTOM;
		return ctrl;
	}
	
	
	public static Control alignVertCenter(Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.verticalAlignment = SWT.CENTER;
		return ctrl;
	}

	
	public static Control alignHorzCenter(Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.horizontalAlignment = SWT.CENTER;
		return ctrl;
	}

	
	public static Control alignRight(Control ctrl) {
		gridData(ctrl).horizontalAlignment = SWT.RIGHT;
		return ctrl;
	}
	
	
	public static Control widthHint(int hint, Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.widthHint = hint;
		return ctrl;
	}
	
	
	public static Control heightHint(int hint, Control ctrl) {
		GridData gd = gridData(ctrl);
		gd.heightHint = hint;
		return ctrl;
	}
	
	
	/**
	 * if layout manager of composite is not instance of {@link GridLayout}
	 * creates new {@link GridLayout} and sets it to composite. if layout
	 * manager of composite already {@link GridLayout} just returns it
	 * 
	 * @param panel
	 * @return
	 */
	public static GridLayout gridLayout(Composite panel) {
		if (!(panel.getLayout() instanceof GridLayout)) {
			GridLayout gridLayout = new GridLayout();
			panel.setLayout(gridLayout);
		}
		
		return (GridLayout) panel.getLayout();
	}
	
	
	public static GridLayout numColumns(int numColumns, GridLayout gridLayout) {
		gridLayout.numColumns = numColumns;
		return gridLayout;
	}

	
	/**
	 * sets marigins to zero
	 * 
	 * @param gridLayout
	 * @return
	 */
	public static GridLayout noMargins(GridLayout gridLayout) {
		gridLayout.marginHeight = gridLayout.marginWidth = 0;
		return gridLayout;
	}
	
	
	public static GridLayout equalColumns(boolean equal, GridLayout gridLayout) {
		gridLayout.makeColumnsEqualWidth = equal;
		return gridLayout;
	}


	public static GridLayoutObj gridLayoutObj(Composite panel) {
		return new GridLayoutObj(panel);
	}
}
